package com.yundahh.u8c.dao.base;

import com.yundahh.u8c.config.U8CConfig;
import com.yundahh.u8c.entity.base.U8CResult;
import com.yundahh.u8c.enums.OperationType;
import com.yundahh.u8c.exception.U8CApiException;
import com.yundahh.u8c.util.HttpUtils;
import com.yundahh.u8c.util.JsonUtils;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

public abstract class U8CBaseDao<T> {

    protected U8CConfig config;
    private final Type genericsType;//子类的泛型类型

    protected Map headerMap;

    public void appendHeader(String key,String value){
        headerMap.put(key,value);
    }


    public Type getGenericsType() {
        return genericsType;
    }

    public abstract String getApiUrl();

    public U8CBaseDao(U8CConfig config) {
        this.headerMap=config.getHeaders();
        this.config = config;
        Type superClass = getClass().getGenericSuperclass();
        if (superClass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) superClass;
            if (parameterizedType.getRawType() == U8CBaseDao.class) {
                genericsType = parameterizedType.getActualTypeArguments()[0];
            } else {
                throw new RuntimeException("U8CBaseDao must be directly extended with type parameters.");
            }
        } else {
            //throw new RuntimeException("Missing type parameter.");
            genericsType=null;
        }
    }

    public U8CResult<T> send(OperationType operationType, HashMap params) throws IOException, U8CApiException {
        return send(operationType, JsonUtils.object2Json(params));
    }

    public U8CResult<T> send(OperationType operationType,String json) throws IOException, U8CApiException {
        String jsonResult = HttpUtils.sendPost(config.getServerUrl()+getApiUrl()+"/"+operationType.getValue(), headerMap, json);
        U8CResult<T> parse =null;
        switch (operationType){
            case INSERT:
            case SAVE:
            case SAVE_APPROVE:
            case UPDATE:
                parse = JsonUtils.parseInsert(jsonResult, getGenericsType());
                break;
            case APPROVE:
                parse = JsonUtils.parseStringData(jsonResult);
                break;
            default:
                parse = JsonUtils.parseQuery(jsonResult, getGenericsType());
        }
        return parse;
    }
}
